 var row = 
	{
		init: function()
			{
				this.idioma = new Ext.form.ComboBox
					({
						fieldLabel: 'Idioma',
						name: 'data[' + _PHP_.model + '][idioma_id]',
						allowBlank: false,
						hiddenName: 'data[' + _PHP_.model + '][idioma_id]',
						editable: false,
						valueField: 'id',
						displayField: 'nome',
						mode: 'local',
						triggerAction: 'all',
						lastQuery: '',
						store: new Ext.data.SimpleStore
							({
								fields: ['id', 'nome'],
								data: _PHP_.form.idiomas
							})
					});
					
				this.pais = new Ext.form.ComboBox
					({
						fieldLabel: 'País',
						name: 'data[' + _PHP_.model + '][pais_id]',
						allowBlank: false,
						hiddenName: 'data[' + _PHP_.model + '][pais_id]',
						editable: false,
						valueField: 'id',
						displayField: 'nome',
						mode: 'local',
						triggerAction: 'all',
						lastQuery: '',
						store: new Ext.data.SimpleStore
							({
								fields: ['id', 'nome'],
								data: _PHP_.form.paises
							})
					});
					
				this.nome = new Ext.form.TextField
					({
						fieldLabel: 'Nome',
						name: 'data[' + _PHP_.model + '][nome]',
						allowBlank: false,
						width: 350,
						_maxLength: 40
					});
					
				this.organizacao = new Ext.form.TextField
					({
						fieldLabel: 'Organização',
						name: 'data[' + _PHP_.model + '][organizacao]',
						allowBlank: false,
						width: 350
					});
					
				this.tags = new Ext.ux.BoxSelect
					({
						fieldLabel: 'Tags',
						name: 'data[Tag][Tag][]',
						queryParam: 'tag',
						mode: 'remote',
						displayField: 'nome',
						valueField: 'nome',
						store: new Ext.data.Store
							({
								url: _PHP_.url.tag,
								reader: new Ext.data.JsonReader
									(
										{
											totalProperty: 'total',
											root: 'rows',
											id: 'id'
										},
										['id', 'nome']
									)
							}),
						minChars: 1,
						_maxLength: 999999,
						width: 350
					});
					
				this.informacoes = new Ext.form.FieldSet
					({
						title: 'Informações',
						autoHeight: true,
						defaultType: 'textfield',
						items: [this.idioma, this.pais, this.nome, this.organizacao, this.tags]
					});
				
				var removeRow = function(record, rowIndex, cm, store)
					{
						for (i = 0; i < cm.getColumnCount(); i++) 
						{
							var cellEditor = cm.getCellEditor(i, rowIndex);
							var index = cm.getDataIndex(i);
							
							if (typeof cellEditor != 'undefined' &&
								typeof record.get(index) == 'undefined') 
							{
								store.remove(record);
								break;
							}
						}
					};
				var listeners = 
					{
						'focus': function(field)
							{
								field.ignoreBlurEvent = false;
								if (Ext.util.Format.htmlDecode(field.getValue()) === '&nbsp;') 
								{
									field.setValue('');
								}
							},
						'specialkey': function(field, e)
							{
								var keypressed = e.getKey();
								var editor = field.parent;
								var grid = editor.parent;
								var store = grid.getStore();
								var rowIndex = store.getCount() - 1;
								var record = store.getAt(rowIndex);
								var cm = grid.getColumnModel();
								var lastColumn = (cm.getColumnCount() == editor.col + 1);
								
								if((lastColumn && keypressed == Ext.EventObject.ESC) ||
								   (Ext.isEmpty(field.getValue().trim()) && (keypressed == Ext.EventObject.TAB || keypressed == Ext.EventObject.ESC || keypressed == Ext.EventObject.ENTER))) 
								{
									field.ignoreBlurEvent = true;
									grid.stopEditing(true);
									removeRow(record, rowIndex, cm, store);
									return false;
								}
								else
								{
									var nextColumnIndex = editor.col + 1;

									if (cm.getColumnCount() > nextColumnIndex)
									{
										field.ignoreBlurEvent = true;
										if(keypressed == Ext.EventObject.ENTER) grid.startEditing(rowIndex, nextColumnIndex);
									}
								}
							},
						'blur': function(field)
							{
								var editor = field.parent;
								var grid = editor.parent;
								var cm = grid.getColumnModel();
								var lastColumn = (cm.getColumnCount() == editor.col + 1);
								
								if(!field.ignoreBlurEvent && (!lastColumn || (lastColumn && Ext.isEmpty(field.getValue().trim()))))
								{
									var store = grid.getStore();
									var rowIndex = store.getCount() - 1;
									var record = store.getAt(rowIndex);
									
									grid.stopEditing(true);
									removeRow(record, rowIndex, cm, store);
								}
							}
					};
					
				var enderecoGrid = new Ext.grid.EditorGridPanel(gridX.cloneConfig
					({
						cancelNextRowEdit: false,
						width: 500,
						height: 200,
						title: null,
						el: null,
						tbar: [
							{
								xtype: 'tbbutton',
								text: 'Adicionar',
								icon: _PHP_.url.incroot + 'img/admin/ext/application_add.png',
								cls: 'x-btn-text-icon',
								handler: function()
								{
									var store = this.getStore();
									var row = store.getCount();
									store.insert(row, new Ext.data.Record({}));
									this.startEditing(row, 0);
								}
							}, 
							{
								xtype: 'tbbutton',
								text: 'Editar',
								icon: _PHP_.url.incroot + 'img/admin/ext/application_edit.png',
								cls: 'x-btn-text-icon',
								handler: function()
								{
									var sm = this.getSelectionModel();
									
									if (sm.getCount() < 1) 
									{
										Ext.MessageBox.alert('Atenção', 'Por favor selecione o registro que deseja editar.');
									}
									else 
									{
									
										if (sm.getCount() > 1) 
										{
											Ext.MessageBox.alert('Atenção', 'Por favor selecione apenas um registro.');
										}
										else 
										{
											this.startEditing(this.getStore().indexOf(sm.getSelected()), 0);
										}
									}
								}
							}, 
							{
								xtype: 'tbbutton',
								text: 'Apagar',
								icon: _PHP_.url.incroot + 'img/admin/ext/application_delete.png',
								cls: 'x-btn-text-icon',
								handler: function()
								{
								
									if (this.getSelectionModel().getCount() < 1) 
									{
										Ext.MessageBox.alert('Atenção', 'Por favor selecione o registro que deseja apagar.');
									}
									else 
									{
										var store = this.getStore();
										var sm = this.getSelectionModel();
										
										if (this.getSelectionModel().getCount() > 1) 
										{
											Ext.MessageBox.confirm('Atenção', 'Tem certeza de que deseja apagar os registros selecionados?', function(button)
											{
											
												if (button == 'yes') 
												{
													var selection = sm.getSelections();
													for (var i = 0; i < selection.length; i++) 
													{
														store.remove(selection[i]);
													}
												}
											}, this);
										}
										else 
										{
											store.remove(sm.getSelected());
										}
									}
								}
							}],
						bbar: null,
						plugins: null,
						doEdit: null,
						doDelete: null,
						formWin: null,
						form: null,
						sm: new Ext.grid.RowSelectionModel
							({
								singleSelect: false,
								moveEditorOnEnter: false
							}),
						cm: new Ext.grid.ColumnModel
							([
								{
									header: 'Endereço',
									dataIndex: 'endereco',
									width: 100,
									sortable: true,
									editor: new Ext.form.TriggerField
										({
											triggerClass: 'trigger-world',
											onTriggerClick: function()
												{
													var gmapWin = this.parent.parent.gmapWin
													gmapWin.lastEditedField = this;
													gmapWin.lastEditedField.suspendEvents();
													
													var value = Ext.util.Format.htmlEncode(this.getValue());
													value = !Ext.isEmpty(value) ? value : 'R. Pamplona, 1197 - Jardim Paulista, São Paulo - SP, 01405-002, Brazil';
													
													if (gmapWin.rendered && gmapWin.gmapPanel && gmapWin.gmapPanel.rendered) 
													{
														gmapWin.gmapPanel.geoCodeLookup(value, {}, true, true);
													}
													else 
													{
														var setAddressOnMapReady = function(win)
															{
																if (win.gmapPanel && win.gmapPanel.rendered) 
																{
																	gmapPanel.geoCodeLookup(value, {}, true, true);
																}
																else 
																{
																	win.gmapPanel.on('render', function(panel)
																		{
																			var oldfunc = panel.onMapReady;
																			panel.onMapReady = function()
																				{
																					oldfunc.apply(panel);
																					panel.geoCodeLookup(value, {}, true, true);
																				};
																		}, {single: true});
																}
															}
														
														if(gmapWin.rendered)
														{
															setAddressOnMapReady(gmapWin);	
														}
														else
														{
															gmapWin.on('render', function(win)
																{
																	setAddressOnMapReady(win);
																}, {single: true});
														}
													}
													
													gmapWin.show();
												},
											enableKeyEvents: true,
											listeners: listeners
										})
								},
								{
									header: 'Tipo',
									dataIndex: 'nome',
									width: 25,
									sortable: true,
									editor: new Ext.form.TextField
										({
											enableKeyEvents: true,
											listeners: listeners
										})
								}
							]),
						ds: new Ext.data.JsonStore
							({
								url: _PHP_.url.data,
								id: 'id',
								root: 'rows',
								totalProperty: 'total',
								remoteSort: false,
								baseParams: 
									{
										sort: 'Nome',
										dir: 'ASC'
									},
								fields: ['id', 'endereco', 'nome']
							}),
						listeners: 
							{
								'render': function(grid)
									{
										this.setReferences(grid);
										
										Ext.MessageBox.wait('Aguarde', 'Configurando ...');
										var interval = setInterval(function()
											{
												if(grid.gmapWin)		
												{
													clearInterval(interval);
													Ext.MessageBox.hide();
													grid.gmapWin.parent = grid;
												}
											}, 300);
									}
							},
						gmapWin: new Ext.Window
							({
								layout: 'fit',
								title: 'Buscar endereço',
								closeAction: 'hide',
								width: 600,
								height: 600,
								modal: true,
								items: 
									[
										new Ext.ux.GMapPanel
											({
												zoomLevel: 14,
												gmapType: 'map',
												id: 'my_map',
												mapConfOpts: ['enableScrollWheelZoom', 'enableDoubleClickZoom', 'enableDragging'],
												mapControls: ['GSmallMapControl', 'GMapTypeControl', 'NonExistantControl'],
												setCenter: 
													{
														geoCodeAddr: 'R. Pamplona, 1197 - Jardim Paulista, São Paulo - SP, 01405-002, Brazil'
													},
												listeners:
													{
														'render': function(obj)
															{
																var interval = setInterval(function()
																	{
																		if(obj.rendered && !Ext.MessageBox.isVisible())
																		{
																			 Ext.MessageBox.wait('Aguarde', 'Configurando mapa');	
																		}
																		
																		var map = obj.getMap();
																		
																		if(map) 
																		{
																			clearInterval(interval);
																			
																			var markers;
																			
																			obj.localSearch = new google.maps.LocalSearch
																				({
																					onSearchCompleteCallback: function(searcher)
																						{
																							Ext.each(this.intervals, function(interval)
																								{
																									clearInterval(interval);
																								});
													                                	},
																					onGenerateMarkerHtmlCallback: function(marker, html, result)
																						{
																							var html = new Ext.Element(html);
																							
																							Ext.each(html.query('a.gs-title'), function(item)
																								{
																									item.target = '_self';
																									item.href = 'javascript:;';
																									item.onclick = function()
																										{
																											obj.parent.setAddressIntoRow(result);
																										};
																								});
																							Ext.each(html.query('div.gs-directions, div.gs-directions-to-from'), function(item)
																								{
																									new Ext.Element(item).remove();
																								});
																							
																							return html.dom;
													                                	},
																					onMarkersSetCallback: function(markers)
																						{
																							var store = enderecoGrid.getStore();
																							var cm = enderecoGrid.getColumnModel();
																							var records = store.getCount();
																							
																							Ext.each(markers, function(marker)
																								{
																									var intervals = this.intervals;
																									var interval = intervals[intervals.lenght] = setInterval(function()
																										{
																											var result = Ext.query('img[src="' + marker.marker.getIcon().image + '"]');
																											
																											if(result[0]) 
																											{
																												clearInterval(interval);
																												delete intervals[intervals.indexOf(interval)];
																												
																												new Ext.Element(result[0]).on('click', function(e)
																													{
																														e.stopEvent();
																														e.stopPropagation();
																														
																														obj.parent.setAddressIntoRow(marker.result);
																													});
																											}
																										}, 300);
																								}, this);
																								
																							$('div.gmls-attribution, a.gmls-more-results').each(function()
																								{
																									$(this).remove();
																								});
																						}
																				});
																			obj.localSearch.intervals = [];
																			
																			map.addControl(obj.localSearch, new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(2,4)));
																			map.addControl(new GOverviewMapControl(new GSize(100,100)));
																			Ext.MessageBox.hide();
																			obj.localSearch.focus();
																		}
																	}, 500);
															}
													}
											})
									],
								listeners:
									{
										'render': function()
											{
												this.gmapPanel = this.items.get(0);
												this.gmapPanel.parent = this;
											},
										'hide': function()
											{
												this.lastEditedField.resumeEvents();
												
												var editor = this.lastEditedField.parent;
												editor.parent.startEditing(editor.row, editor.col + 1);
												
												if($('.gmls-clear-results'))
												{
													$('.gmls-clear-results').click();
												}
											}
									},
								setAddressIntoRow: function(result)
									{
										var grid = this.parent;
										var store = grid.getStore();
										var sm = grid.getSelectionModel();
										var selection = sm.getSelections();
										
										if(row)
										{
											selection[0].set('endereco', result.addressLines.join(' '));
											grid.getView().refresh();
										}
									}
							}),
						setReferences: function(grid)
							{
								grid.getTopToolbar().items.each(function(item)
									{
										Ext.getCmp(item.id).scope = grid;
									});
									
								var cm = grid.getColumnModel();
								for (i = 0; i < cm.getColumnCount(); i++) 
								{
									var editor = cm.getCellEditor(i, 0);
									
									if (typeof editor != 'undefined') 
									{
										editor.field.parent = editor;
										editor.parent = grid;
									}
								}
							}
					}));
					
				this.enderecos = new Ext.form.FieldSet
					({
						xtype: 'fieldsetgrid',
						title: 'Endereços',
						height: 260,
						items: enderecoGrid,
						listeners: 
							{
								'render': function(fielset)
									{
										var fielsetWidth = fielset.getInnerWidth();
										var grid = fielset.items.get(0);
										
										if (!grid.rendered) 
										{
											grid.on('render', function(grid)
												{
													grid.setSize(fielsetWidth - 60, 200);
												});
										}
									}
							}
					});
					
				this.emails = new Ext.form.FieldSet
					({
						xtype: 'fieldsetgrid',
						title: 'Emails',
						height: 260,
						items: enderecoGrid.cloneConfig
							({
								gmapWin: null,
								sm: new Ext.grid.RowSelectionModel
									({
										singleSelect: false,
										moveEditorOnEnter: false
									}),
								cm: new Ext.grid.ColumnModel
									([
										{
											header: 'Email',
											dataIndex: 'email',
											width: 100,
											sortable: true,
											editor: new Ext.form.TextField
												({
													enableKeyEvents: true,
													listeners: listeners
												})
										}, 
										{
											id: 'primario',
											header: 'Primário',
											dataIndex: 'primario',
											width: 15,
											align: 'center'
										}
									]),
								ds: new Ext.data.JsonStore
									({
										url: _PHP_.url.data,
										id: 'id',
										root: 'rows',
										totalProperty: 'total',
										remoteSort: false,
										baseParams: 
											{
												sort: 'primario',
												dir: 'DESC'
											},
										fields: ['id', 'email', 'primario'],
										listeners: 
											{
												'add': function(store, records, index)
													{
														if (store.getCount() == 1) 
														{
															store.getAt(0).set('primario', 1);
														}
													}
											}
									}),
								listeners:
									{
										'render': function(grid)
											{
												this.setReferences(grid);
												
												var cm = grid.getColumnModel();
												var primario = cm.getColumnById('primario');
												
												if(typeof primario != 'undefined') 
												{
													grid.processRadio = function(record_id)
														{
															this.getStore().each(function(record)
															{
																record.set('primario', (record.id != record_id) ? 0 : 1);
															});
														};
													primario.renderer = function(val, cell, record, rowIndex, colIndex, store)
														{
															return '<input onclick="row.emails.items.get(0).processRadio(\'' + record.id + '\')" type="radio" value="true" name="_primario_' + rowIndex + '" ' + (val == 1 ? 'checked="checked"' : '') + '/>';
														};
												}
											}
									}
							}),
						listeners: 
							{
								'render': function(fielset)
									{
										var fielsetWidth = fielset.getInnerWidth();
										var grid = fielset.items.get(0);
										
										if (!grid.rendered) 
										{
											grid.on('render', function(grid)
											{
												grid.setSize(fielsetWidth - 60, 200);
											})
										}
									}
							}
					});
					
				this.telefones = new Ext.form.FieldSet
					({
						xtype: 'fieldsetgrid',
						title: 'Telefones',
						height: 260,
						items: enderecoGrid.cloneConfig
							({
								gmapWin: null,
								sm: new Ext.grid.RowSelectionModel
									({
										singleSelect: false,
										moveEditorOnEnter: false
									}),
								cm: new Ext.grid.ColumnModel
									([
										{
											header: 'Número',
											dataIndex: 'numero',
											width: 100,
											sortable: true,
											editor: new Ext.form.TextField
												({
													enableKeyEvents: true,
													listeners: listeners
												})
										},
										{
											header: 'Tipo',
											dataIndex: 'nome',
											width: 25,
											sortable: true,
											editor: new Ext.form.TextField
												({
													enableKeyEvents: true,
													listeners: listeners
												})
										}
									]),
								ds: new Ext.data.JsonStore
									({
										url: _PHP_.url.data,
										id: 'id',
										root: 'rows',
										totalProperty: 'total',
										remoteSort: false,
										baseParams: 
											{
												sort: 'nome',
												dir: 'ASC'
											},
										fields: ['id', 'numero', 'nome']
									}),
								listeners: 
									{
										'render': function(grid)
											{
												this.setReferences(grid);
											}
									}		
							}),
						listeners: 
							{
								'render': function(fielset)
								{
									var fielsetWidth = fielset.getInnerWidth();
									var grid = fielset.items.get(0);
									
									if (!grid.rendered) 
									{
										grid.on('render', function(grid)
											{
												grid.setSize(fielsetWidth - 44, 200);
											});
									}
								}
							}
					});
					
				this.informacoes.items.each(function()
					{
						util.applyDefaults(this, gridX.form.defaults);
					});
				
				Ext.get(document).on('keypress', function(event)
					{
						if(event.ctrlKey && gridX.lastSelectedCell)
						{
							var keycode = event.getKey();
							
							if(keycode == 67 || keycode == 99)
							{
								gridX.lastSelectedCell.highlight("ffff9c",
									{
										callback: function()
											{
												delete gridX.lastSelectedCell;
											}
									});
							}
						}
					});
				gridX.on('cellclick', function(grid, rowIndex, columnIndex, event)
					{
						var record = grid.getStore().getAt(rowIndex);
						var fieldName = grid.getColumnModel().getDataIndex(columnIndex);
						var data = record.get(fieldName);
						
						gridX.lastSelectedCell = new Ext.Element(grid.getView().getCell(rowIndex, columnIndex));
						
						if(!document.body.clipboard) 
						{
							document.body.clipboard = Ext.DomHelper.append(Ext.get(document.body), '<textarea style="position: absolute; top: -1000px; left: -1000px;" />');
						}
						document.body.clipboard.value = data;
						document.body.clipboard.focus();
						document.body.clipboard.select();
					});
					
				gridX.form.add(this.informacoes, this.enderecos, this.emails, this.telefones);
				gridX.form.on('beforesave', function(form)
					{
						for (var i = 0; i < form.items.length; i++) 
						{
							var item = form.items.get(i);
							
							if (item.xtype == 'fieldsetgrid') 
							{
								var store = item.items.get(0).getStore();
								store.each(function(record)
									{
									
										if (!Ext.isEmpty(record.get('email')) && Ext.isEmpty(record.get('primario'))) 
											record.set('primario', 0);
										for (var idx in record.data) 
										{
											var attribute = record.data[idx];
											
											if (!Ext.isEmpty(attribute) && (typeof attribute == 'string' || typeof attribute == 'boolean' || typeof attribute == 'number')) 
											{
												form.add(new Ext.form.Hidden
													({
														name: 'data[' + _PHP_.model + '][' + item.title.toLowerCase().replace(/ç/ig, 'c') + '][' + idx + '][]',
														value: attribute,
														xtype: 'hidden'
													}));
											}
										}
									});
							}
						}
						var afterlayout = function(form, layout)
						{
							form.un('afterlayout', afterlayout);
							form.doSubmit(form.parent);
						};
						form.on('afterlayout', afterlayout);
						form.doLayout();
					});
					
				gridX.form.on('success', function(form, response)
					{
						form.items.each(function(item)
							{
								if (item.getXType() == 'hidden') 
								{
									form.remove(item, true);
									item.el.remove();
								}
							});
						
						form.defaultEvents.success.apply(form.parent);
					});
					
				gridX.form.form.on('reset', function(grid)
					{
						var form = grid.form;
						for (var i = 0; i < form.items.length; i++) 
						{
							var item = form.items.get(i);
							
							if (item.xtype == 'fieldsetgrid') 
							{
								item.items.get(0).getStore().removeAll();
							}
						}
					});
			}
	};
